package org.su.webadapter;



import org.su.generalmvc.core.*;
import org.su.generalmvc.util.Assert;
import org.su.webadapter.webimpl.ServiceContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * xssh框架核心处理器
 * <p>
 * xssh框架是基于struts2，springmvc，以及原ssh框的原理基础上开发而成的一个简单mvc框架. 所以他具有以下几个特性：
 * </p>
 * <ul>
 * <li>xssh的默认配置文件为xssh.xml文件，位于：WEB-INF/文件夹下</li>
 * <li>所有的action处理都是从拦截器开始，也是到拦截器结束</li>
 * <li>目前xssh框架仅支持两种视图渲染器，json和velocity</li>
 * <li>xssh框架支持扩展拦截器来满足项目的需求，包括视图的渲染，权限的验证等等.
 * 定义拦截很简单，您只需要继承com.xssh.mvc.web.core.Interceptor接口</li>
 * <li>xssh框架也支持用户自定义渲染器，以满足处理不同的视图渲染</li>
 * <li>xssh框架支持你使用spring框架管理各中bean的声明周期，当然你也可以不使用spring.
 * 是否使用spring容器，除了了web.xml中声明加载spring。
 * 你还需要在xssh.xml中的&lt;config&gt;里配置&lt;useSpring&gt;设为false</li>
 * </ul>
 * 
 * 
 * 
 * @author yangchuan
 * @see org.su.generalmvc.core.Interceptor
 */
public class XSSHDispather implements Filter {

	private IXsshApplicationContext xsshContext = null;

	protected final Log logger = LogFactory.getLog(getClass());

	/* The FilterConfig of this filter */
	private FilterConfig filterConfig;

	private ServletContext servletContext;

	@Override
	public void destroy() {

		if (!xsshContext.isSpringContext()) {
			LifeCycleManager.getInstence().destroy();
		}

		xsshContext.destroy();
	}



	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {

        /**
         * 类型强制转换，尽量少用，会有一定性能影响。
         */
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		request.setCharacterEncoding(xsshContext.getConfig().getEncoding());
		response.setContentType("text/html; charset="
				+ xsshContext.getConfig().getEncoding());
        ((HttpServletResponse)response).setHeader("Access-Control-Allow-Origin", "*");

		String path = httpRequest.getRequestURI();
		String sc = httpRequest.getContextPath();
		int length = path.indexOf(';');
		if(length>0){
			path = path.substring(sc.length(),path.indexOf(";"));
		}else{
			path = path.substring(sc.length());
		}
		ActionProxy ap = xsshContext.getActions().get(path);
		if (ap != null) {
			new DefaultActionInvocation(ap, request, response)
					.parseRequest();
		} else {
			chain.doFilter(request, response);
		}

	}
	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {

		try {

			if (xsshContext == null) {
				Assert.notNull(filterConfig, "FilterConfig must not be null");
				if (logger.isDebugEnabled()) {
					logger.debug("Initializing filter '"
							+ filterConfig.getFilterName() + "'");
				}

				this.filterConfig = filterConfig;
				InitialContext.getInstance().init(filterConfig.getInitParameter("mvc-config"),getServletContext());
				xsshContext = InitialContext.getInstance().getContext();
			}

		} catch (Exception e) {
			throw new ServletException(e);
		}
	}

	private final ServiceContext getServletContext() {
		this.servletContext = (this.filterConfig != null ? this.filterConfig
				.getServletContext() : this.servletContext);
        return new ServiceContext(servletContext);
	}

}
